/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tictactoe;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
/**
 *
 * @author Kevin O
 */
public class MenuPanel extends JPanel 
implements ActionListener, MouseListener, MouseMotionListener{
    ActionListener action_listener;
    
    //Menu Buttons
    JPanel newgame_panel;
    JButton newgame_button;
    JButton undo_button;
    JButton redo_button;
    JRadioButton threatdisplay_radio;
    JButton diagonaldisplay_button;
    
    //Radio Buttons for Rotating the board
    JPanel rotation_panel;
    ButtonGroup rotation_group;
    JLabel rotation_label;
    JRadioButton wx_radio;
    JRadioButton wy_radio;
    JRadioButton wz_radio;
    JRadioButton xy_radio;
    JRadioButton xz_radio;
    JRadioButton yz_radio;
    
    //New Game options
    private JComboBox multi_box;
    private JComboBox diff_box;
    
    //Stores the options chosen
    boolean single_player = true;
    int difficulty = 0;
    
    //Board/Output section
    OutputPanel output_panel;
    
    boolean menu_enabled = true;
    
    //Game
    Game game;
    
    public MenuPanel(){
        
        //Initialize New Game Panel
        newgame_panel = new JPanel();
        BoxLayout newgamelayout = new BoxLayout(newgame_panel, BoxLayout.PAGE_AXIS);
        newgame_panel.setLayout(newgamelayout);
        Border basicborder = BorderFactory.createLineBorder(Color.BLACK);
        newgame_panel.setBorder(basicborder);
        
        //Initialize buttons
        newgame_button = new JButton("New Game");
        newgame_button.addActionListener(this);
        newgame_button.setToolTipText("Starts a new single or multiplayer game");
        
        undo_button = new JButton("Undo");
        undo_button.addActionListener(this);
        undo_button.setToolTipText("Undoes the previous user move");
        
        redo_button = new JButton("Redo");
        redo_button.addActionListener(this);
        redo_button.setToolTipText("Redoes the most recently undones move");
        
        threatdisplay_radio = new JRadioButton("Highlight Threats");
        threatdisplay_radio.addActionListener(this);
        threatdisplay_radio.setToolTipText("Highlights squares when one player gets 3 out of 4 in a row");
        
        diagonaldisplay_button = new JButton("Quick Diagonals");
        diagonaldisplay_button.addActionListener(this);
        diagonaldisplay_button.setToolTipText("Displays a quick reference of all diagonals and how full they are."
                + "\nClick one of the sets of circles to return to the board and highlight the diagonal.");
        
        //Initialize Board Rotations radio buttons
        rotation_panel = new JPanel();
        BoxLayout rotationlayout = new BoxLayout(rotation_panel, BoxLayout.PAGE_AXIS);
        rotation_panel.setLayout(rotationlayout);
        
        rotation_label = new JLabel("Sub-Board Coordinates");
        rotation_panel.setBorder(basicborder);
        
        wx_radio = new JRadioButton("W / X");
        wx_radio.addActionListener(this);
        wx_radio.setSelected(true);
        wx_radio.setToolTipText("Changes which dimensions are used to draw the smaller boards");
        
        wy_radio = new JRadioButton("W / Y");
        wy_radio.addActionListener(this);
        wy_radio.setToolTipText("Changes which dimensions are used to draw the smaller boards");
        
        wz_radio = new JRadioButton("W / Z");
        wz_radio.addActionListener(this);
        wz_radio.setToolTipText("Changes which dimensions are used to draw the smaller boards");
        
        xy_radio = new JRadioButton("X / Y");
        xy_radio.addActionListener(this);
        xy_radio.setToolTipText("Changes which dimensions are used to draw the smaller boards");
        
        xz_radio = new JRadioButton("X / Z");
        xz_radio.addActionListener(this);
        xz_radio.setToolTipText("Changes which dimensions are used to draw the smaller boards");
        
        yz_radio = new JRadioButton("Y / Z");
        yz_radio.addActionListener(this);
        yz_radio.setToolTipText("Changes which dimensions are used to draw the smaller boards");
        
        rotation_panel.add(rotation_label);
        rotation_panel.add(wx_radio);
        rotation_panel.add(wy_radio);
        rotation_panel.add(wz_radio);
        rotation_panel.add(xy_radio);
        rotation_panel.add(xz_radio);
        rotation_panel.add(yz_radio);
        
        
        //Set up the group of Radio Buttons
        rotation_group = new ButtonGroup();
        rotation_group.add(wx_radio);
        rotation_group.add(wy_radio);
        rotation_group.add(wz_radio);
        rotation_group.add(xy_radio);
        rotation_group.add(xz_radio);
        rotation_group.add(yz_radio);
        
        //Initialize the combo boxes
        String[] multi_options = { "Single Player", "Multiplayer" };
        multi_box = new JComboBox(multi_options);
        multi_box.setMaximumSize(new Dimension(150, 30));
        multi_box.setAlignmentX(-10);
        multi_box.addActionListener(this);
        String[] diff_options = { "Easy", "Medium", "Hard" };
        diff_box = new JComboBox(diff_options);
        diff_box.addActionListener(this);
        diff_box.setMaximumSize(new Dimension(150, 30));
        diff_box.setAlignmentX(-10);
        
        newgame_panel.add(newgame_button);
        newgame_panel.add(multi_box);
        newgame_panel.add(diff_box);
        
        //Set up the layout
        //GridLayout gridlayout = new GridLayout(6, 1);
        BoxLayout boxlayout = new BoxLayout(this, BoxLayout.PAGE_AXIS);
        setLayout(boxlayout);
        
        //Add all of the elements
        /*add(newgame_button);
        add(multi_box);
        add(diff_box);*/
        add(newgame_panel);
        add(undo_button);
        add(redo_button);
        add(rotation_panel);
        /*add(rotation_label);
        add(wx_radio);
        add(wy_radio);
        add(wz_radio);
        add(xy_radio);
        add(xz_radio);
        add(yz_radio);*/
        add(threatdisplay_radio);
        add(diagonaldisplay_button);
        
        
        //initialize the game
        game = new Game(GameStatus.InProgressSingle);
        game.setShowThreats(false);
        
        output_panel = new OutputPanel(this, this, game);
        
    }
    
    ///////////////
    // LISTENERS //
    ///////////////
    
    @Override 
    public void actionPerformed(ActionEvent e){
        
        if (e.getSource() == newgame_button){
            game.newGame();
            game.setAiDifficulty(diff_box.getSelectedIndex());
            output_panel.checkTurn();
            output_panel.repaint();
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == undo_button){
            game.undo();
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == redo_button){
            game.redo();
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == wx_radio){
            output_panel.draw_panel.rotation = 0;
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == wy_radio){
            output_panel.draw_panel.rotation = 1;
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == wz_radio){
            output_panel.draw_panel.rotation = 2;
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == xy_radio){
            output_panel.draw_panel.rotation = 3;
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == xz_radio){
            output_panel.draw_panel.rotation = 4;
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == yz_radio){
            output_panel.draw_panel.rotation = 5;
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == threatdisplay_radio){
            game.setShowThreats(threatdisplay_radio.isSelected());
            output_panel.draw_panel.repaint();
        }
        
        else if (e.getSource() == diagonaldisplay_button)
            toggleBoardDisplay();
        
        else if (e.getSource() == multi_box){
            diff_box.setEnabled(multi_box.getSelectedIndex() == 0);
        }
    }
    
    public void mouseExited(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    
    //Handles interaction with the Board
    public void mouseClicked(MouseEvent e){
        //Get the screen coordinates
        if(game.winState() == GameStatus.InProgressSingle || game.winState() == GameStatus.InProgressMultiplayer){
            int height = output_panel.draw_panel.getHeight();
            int width = output_panel.draw_panel.getWidth();
            double[] screencoords = new double[2];
            screencoords[0] = (double)e.getX()/width;
            screencoords[1] = (double)e.getY()/height;
        
        
            if(output_panel.draw_panel.display_mode == DrawPanel.BOARD_DISPLAY){
                //Converts the position on the screen to the board's coordinates
                int[] boardcoords;
                boardcoords = convertScreenToBoard(screencoords);
                System.out.println("PLACE AT ("+boardcoords[0]+", "+boardcoords[1]+", "+boardcoords[2]+", "+boardcoords[3]+")");
                game.makeMove(boardcoords[0], boardcoords[1], boardcoords[2], boardcoords[3]);
                output_panel.draw_panel.diagonal_is_highlighted = false;
            }
            else{
                //Accesses Diagonals based on location clicked
                int diagonal = (int)(screencoords[0] * 8) + (int)(screencoords[1] * 9) * 8;
                System.out.println("HIGHLIGHT DIAGONAL "+diagonal);
                output_panel.draw_panel.highlighted_squares = game.getDiagonals()[diagonal];
                output_panel.draw_panel.diagonal_is_highlighted = true;
                toggleBoardDisplay();
            }
            
            output_panel.checkTurn();
            output_panel.draw_panel.repaint();
        }
    }
    public void mouseMoved(MouseEvent e){}
    public void mouseDragged(MouseEvent e){}
    
    ///////////////////////
    // UTILITY FUNCTIONS //
    ///////////////////////
    
    private void toggleBoardDisplay(){
        if (output_panel.draw_panel.display_mode == DrawPanel.BOARD_DISPLAY){
                //change button displays
                diagonaldisplay_button.setText("Back to Board");
                undo_button.setEnabled(false);
                redo_button.setEnabled(false);
                newgame_button.setEnabled(false);
                wx_radio.setEnabled(false);
                wy_radio.setEnabled(false);
                wz_radio.setEnabled(false);
                xy_radio.setEnabled(false);
                xz_radio.setEnabled(false);
                yz_radio.setEnabled(false);
                threatdisplay_radio.setEnabled(false);
                
                //change output
                output_panel.draw_panel.display_mode = DrawPanel.DIAGONAL_DISPLAY;
                output_panel.repaint();
            }
            else{
                //change button displays
                diagonaldisplay_button.setText("Diagonal Cheat Sheet");
                undo_button.setEnabled(true);
                redo_button.setEnabled(true);
                newgame_button.setEnabled(true);
                wx_radio.setEnabled(true);
                wy_radio.setEnabled(true);
                wz_radio.setEnabled(true);
                xy_radio.setEnabled(true);
                xz_radio.setEnabled(true);
                yz_radio.setEnabled(true);
                threatdisplay_radio.setEnabled(true);
                
                //change output
                output_panel.draw_panel.display_mode = DrawPanel.BOARD_DISPLAY;
                output_panel.repaint();
            }
    }
    
    private void toggleMenuEnabled(){
         menu_enabled  = !menu_enabled;
         
         //change button displays
         diagonaldisplay_button.setEnabled(menu_enabled);
         undo_button.setEnabled(menu_enabled);
         redo_button.setEnabled(menu_enabled);
         newgame_button.setEnabled(menu_enabled);
         wx_radio.setEnabled(menu_enabled);
         wy_radio.setEnabled(menu_enabled);
         wz_radio.setEnabled(menu_enabled);
         xy_radio.setEnabled(menu_enabled);
         xz_radio.setEnabled(menu_enabled);
         yz_radio.setEnabled(menu_enabled);
         threatdisplay_radio.setEnabled(menu_enabled);
    }
    
    
    public int[] convertScreenToBoard(double[] s){
        //int[] b is holds a 4 dimensional coordinate in the form (w,x,y,z)
        int[] b = new int[4];
        int majx = 0;
        int majy = 0;
        int minx = 0;
        int miny = 0;
        
        //Finds the major x coordinate
        if(s[0] < 0.25)
            majx = 0;
        else if(s[0] < 0.5)
            majx = 1;
        else if(s[0] < 0.75)
            majx = 2;
        else
            majx = 3;
        
        //Finds the major y coordinate
        if(s[1] < 0.25)
            majy = 0;
        else if(s[1] < 0.5)
            majy = 1;
        else if(s[1] < 0.75)
            majy = 2;
        else
            majy = 3;
        
        //Finds the minor x coordinate
        if(s[0] - 0.25*majx < 5.0/64.0){
            minx = 0;
        }
        else if(s[0] - 0.25*majx < 1.0/8.0){
            minx = 1;
        }
        else if(s[0] - 0.25*majx < 11.0/64.0){
            minx = 2;
        }
        else{
            minx = 3;
        }
        
        //Finds the minor y coordinate
        if(s[1] - 0.25*majy < 5.0/64.0)
            miny = 0;
        else if(s[1] - 0.25*majy < 1.0/8.0)
            miny = 1;
        else if(s[1] - 0.25*majy < 11.0/64.0)
            miny = 2;
        else
            miny = 3;
        
        //Handle the board rotation
        switch(output_panel.draw_panel.rotation){
            case DrawPanel.ROTATION_WX:
                b[0] = minx;
                b[1] = miny;
                b[2] = majx;
                b[3] = majy;
                break;
            case DrawPanel.ROTATION_WY:
                b[0] = minx;
                b[1] = majx;
                b[2] = miny;
                b[3] = majy;
                break;
            case DrawPanel.ROTATION_WZ:
                b[0] = minx;
                b[1] = majx;
                b[2] = majy;
                b[3] = miny;
                break;
            case DrawPanel.ROTATION_XY:
                b[0] = majx;
                b[1] = minx;
                b[2] = miny;
                b[3] = majy;
                break;
            case DrawPanel.ROTATION_XZ:
                b[0] = majx;
                b[1] = minx;
                b[2] = majy;
                b[3] = miny;
                break;
            case DrawPanel.ROTATION_YZ:
                b[0] = majx;
                b[1] = majy;
                b[2] = minx;
                b[3] = miny;
                break;
        }
            
        return b;
    }
}
